
public class Parcel
{
	/**
	 * @uml.property  name="processed"
	 */
	private boolean processed; // State of parcel
	/**
	 * @uml.property  name="id"
	 */
	private String id; // ID of parcel
	/**
	 * @uml.property  name="type"
	 */
	private char type; // Type (price bracket) of parcel
	/**
	 * @uml.property  name="days"
	 */
	private int days; // Days the parcel has been at the depot
	/**
	 * @uml.property  name="weight"
	 */
	private double weight; // Parcel weight (in KG)
	/**
	 * @uml.property  name="dimensions"
	 * @uml.associationEnd  multiplicity="(1 1)"
	 */
	private Dimensions dimensions; // Length/Width/Height of parcel

	// Constructor: create parcel object from passed arguments

	/**
	 * Creates Parcel object from passed properties
	 * @param id 		String		ID of parcel;
	 * @param days 		int			Number of days parcel has been in depot;
	 * @param id 		double		Weight of parcel;
	 * @param id 		Dimensions	Dimensions object containing length,width,height of parcel;
	 */
    public Parcel (String id, int days, double weight, Dimensions dimensions) {
    	this.processed = false;
    	this.id = id;
    	this.type = id.charAt(0);
    	this.days = days;
    	this.weight = weight;
    	this.dimensions = dimensions;
    }

	// Constructor: create parcel object from string (including validation / error catching)

	/**
	 * Processes line, extracts data, initializes Parcel object
	 * Checks for missing items and invalid data
	 * @param line String to be processed, in format {ID:{TYPE:[A-Z]}\d+},{DAYS:\d+},{WEIGHT:[\d\.]+},{DIMENSIONS:\d+ x \d+ x \d+}
	 */
    public Parcel (String line) {
	    try {
			// create variables to hold the data from each comma-separated section of the input line
			// split the input line into an array of Strings
			String parts [] = line.split(",");
			
			// Parcel ID - String
			this.id = parts[0];
	
			// Parcel type - char, always first char of ID
	    	this.type = id.charAt(0);
			
			// Days in depot - int
			this.days = Integer.parseInt(parts[1]);
	
			// Weight of parcel - int
			this.weight = Double.parseDouble(parts[2]);
			
			// Parcel Dimensions - String
			// Processes string which contains length/width/height of parcel
			// separated by " x ", creates a Dimensions object 
			this.dimensions = new Dimensions(parts[3]);
		}
	
		//for these formatting errors, ignore lines in error and try and carry on

		//this catches trying to convert a String to an integer
		catch (NumberFormatException nfe) {
			String error = "Number conversion error in '" + line + "'  - " + nfe.getMessage();
			error += "\n\nPlease check the Parcel input file; all lines should be in the following format:\n";
			error += "{ID:{TYPE:[A-Z]}\\d+},{DAYS:\\d+},{WEIGHT:[\\d.]+},{DIMENSIONS:\\d+ x \\d+ x \\d+}";
			System.out.println(error);
			System.exit(1);
		}
		//this catches missing items if only one or two items
		//other omissions will result in other errors
		catch (ArrayIndexOutOfBoundsException air) {
			String error = "Not enough items in  : '" + line + "' index position : " + air.getMessage();
			error += "\n\nPlease check the Parcel input file; all lines should be in the following format:\n";
			error += "{ID:{TYPE:[A-Z]}\\d+},{DAYS:\\d+},{WEIGHT:[\\d.]+},{DIMENSIONS:\\d+ x \\d+ x \\d+}";
			System.out.println(error);
			System.exit(1);
		}
    }
    
    // Basic getters (no need for setters yet)
    public boolean getProcessed() {  return processed; }
    /**
	 * @return
	 * @uml.property  name="id"
	 */
    public String getId() {
		return id;
	}
    /**
	 * @return
	 * @uml.property  name="type"
	 */
    public char getType() {
		return type;
	}
	public double getDays() {  return days; }
	/**
	 * @return
	 * @uml.property  name="weight"
	 */
	public double getWeight() {
		return weight;
	}
	/**
	 * @return
	 * @uml.property  name="dimensions"
	 */
	public Dimensions getDimensions() {
		return dimensions;
	}
	
	// Output dimensions as "L x W x H" string
	public String getDimensionsString() { 
		return dimensions.getLength() + " x " + dimensions.getWidth() + " x " + dimensions.getHeight(); 
	}

	// Toggle processed state of parcel, return new state
	public boolean toggleProcessed() {
		if(processed == false) {
			processed = true;
		} else {
			processed = false;
		}
		return processed;
	}

	/**
	 * @uml.property  name="parcelList1"
	 * @uml.associationEnd  inverse="parcel:ParcelList"
	 */
	private ParcelList parcelList1;

	/**
	 * Getter of the property <tt>parcelList1</tt>
	 * @return  Returns the parcelList1.
	 * @uml.property  name="parcelList1"
	 */
	public ParcelList getParcelList1() {
		return parcelList1;
	}

	/**
	 * Setter of the property <tt>parcelList1</tt>
	 * @param parcelList1  The parcelList1 to set.
	 * @uml.property  name="parcelList1"
	 */
	public void setParcelList1(ParcelList parcelList1) {
		this.parcelList1 = parcelList1;
	}

	/**
	 * @uml.property  name="dimensions1"
	 * @uml.associationEnd  inverse="parcel:Dimensions"
	 */
	private Dimensions dimensions1;

	/**
	 * Getter of the property <tt>dimensions1</tt>
	 * @return  Returns the dimensions1.
	 * @uml.property  name="dimensions1"
	 */
	public Dimensions getDimensions1() {
		return dimensions1;
	}

	/**
	 * Setter of the property <tt>dimensions1</tt>
	 * @param dimensions1  The dimensions1 to set.
	 * @uml.property  name="dimensions1"
	 */
	public void setDimensions1(Dimensions dimensions1) {
		this.dimensions1 = dimensions1;
	}
}
